package com.lbssoft.gpsbd.controller;

import com.lbssoft.gpsbd.annotation.LogAnnotation;
import com.lbssoft.gpsbd.model.Result;
import com.lbssoft.gpsbd.model.Role;
import com.lbssoft.gpsbd.model.vo.RoleVo;
import com.lbssoft.gpsbd.service.PermissionService;
import com.lbssoft.gpsbd.service.RoleService;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiImplicitParam;
import io.swagger.annotations.ApiOperation;
import org.apache.shiro.authz.annotation.RequiresPermissions;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.validation.annotation.Validated;
import org.springframework.web.bind.annotation.*;

import javax.validation.constraints.NotNull;
import java.util.*;

@Api("角色管理")
@RestController
@RequestMapping("/roles")
public class RoleController {

	@Autowired
	private RoleService roleService;

	@Autowired
	private PermissionService permissionService;

	@ApiOperation(value="获取角色列表", notes="获取角色列表")
	@RequiresPermissions("system:role:view")
	@RequestMapping(value = "",method = {RequestMethod.GET})
	@ResponseBody
	public Result list() {
		Result result = new Result();
		List<RoleVo> list = roleService.list();
		for(RoleVo role:list){
			role.setPermissions(permissionService.getPermissionIds(role.getId(),"1"));
		}
		result.setData(list);
		return result;
	}

	@ApiOperation(value="添加角色", notes="添加角色")
	@RequiresPermissions("system:role:add")
	@LogAnnotation(targetType = "role",action = "add",remark = "添加角色")
	@RequestMapping(value = "",method = {RequestMethod.POST})
	@ResponseBody
	public Result add(@Validated @RequestBody RoleVo role) {
		Result result = new Result();
		roleService.add(role);
		for(Integer permisId:role.getPermissions()){
			roleService.addRolePermis(role.getId(),permisId);
		}
		return result;
	}

	@ApiOperation(value="删除角色", notes="删除角色")
	@RequiresPermissions("system:role:delete")
	@LogAnnotation(targetType = "role",action = "delete",remark = "删除角色")
	@RequestMapping(value = "/{id}",method = {RequestMethod.DELETE})
	@ResponseBody
	public Result delete(@NotNull @PathVariable int id) {
		Result result = new Result();
		List<Map> list = roleService.getUserByRole(id);
		if(list.size()>0){
			result.setCode(1);
			result.setMsg("角色有用户在使用不可删除");
			return result;
		}
		roleService.delete(id);
		return result;
	}

	@ApiOperation(value="修改角色的权限", notes="修改角色的权限")
	@ApiImplicitParam(paramType="body",name = "role", value = "角色对应的权限", dataType = "RoleVo")
	@LogAnnotation(targetType = "role",action = "update",remark = "修改角色的权限")
	@RequiresPermissions("system:role:update")
	@RequestMapping(value = "",method = {RequestMethod.PUT})
	@ResponseBody
	public Result update(@Validated @RequestBody RoleVo role) {
		Result result = new Result();
		Role r = roleService.getRoleById(role.getId());
		if(r.getRoleKey().equals("root")){
			result.setCode(1);
			result.setMsg("超级管理员角色不可修改");
			return result;
		}

		roleService.udpate(role);

		//获取旧的角色权限
		Set<Integer> permissions = permissionService.getPermissionIds(role.getId(),"0,1");
		//添加新权限
		saveNewPermission(role.getId(), role.getPermissions(), permissions);
		//移除旧的不再拥有的权限
		removeOldPermission(role.getId(), role.getPermissions(), permissions);
		result.setData(role);
		return result;
	}


	/**
	 * 为角色添加新权限
	 *
	 * @param newPerms
	 * @param oldPerms
	 */
	private void saveNewPermission(int roleId, Collection<Integer> newPerms, Collection<Integer> oldPerms) {
		List<Integer> waitInsert = new ArrayList<>();
		for (Integer newPerm : newPerms) {
			if (!oldPerms.contains(newPerm)) {
				waitInsert.add(newPerm);
			}
		}
		if (waitInsert.size() > 0) {
			for(Integer permid:waitInsert){
				roleService.addRolePermis(roleId,permid);
			}
		}
	}

	/**
	 * 删除角色 旧的 不再拥有的权限
	 *
	 * @param roleId
	 * @param newPerms
	 * @param oldPerms
	 */
	private void removeOldPermission(int roleId, Collection<Integer> newPerms, Collection<Integer> oldPerms) {
		List<Integer> waitRemove = new ArrayList<>();
		StringBuilder sb = new StringBuilder();
		for (Integer oldPerm : oldPerms) {
			if (!newPerms.contains(oldPerm)) {
				sb.append(oldPerm);
				sb.append(",");
				waitRemove.add(oldPerm);
			}
		}
		if (waitRemove.size() > 0) {
			roleService.deleteRolePermis(roleId, sb.toString().substring(0,sb.toString().length()-1));
		}
	}
}